import { ref, reactive, computed, toRefs, onBeforeUnmount, watch } from 'vue'
import { useRouter, useRoute } from 'vue-router'
import { useStore } from 'vuex'
import * as types from '@/store/mutation-types'
import { setStorage, getStorage } from '@/utils/storage'
import { searchApi } from '@/api'
export default function(props) {
  const store = useStore()
  const route = useRoute()
  const router = useRouter()
  const inputKeyword = ref(props.keyword || '') 
  const state = reactive({
    // 定义三种状态 init：初始状态, typing: 输入状态, result: 结果状态
    currentStatus: 'init',
    isInit: computed(() => state.currentStatus === 'init'),
    isInput: computed(() => state.currentStatus === 'input'),
    isResult: computed(() => state.currentStatus === 'result'),
    defaultKey: null,
    suggests: [],
    historys: getStorage('search_history') || [],
    placeholder: computed(() => state?.defaultKey?.show_name ?? '请输入搜索关键字')
  })

  let searchTimeout = null

  const handleInput = () => {  
    setStatus('input')
    handleSuggest()      
  }

  const handleSuggest = () => {
    if (inputKeyword.value.trim() === '') {
      clearSuggests()
      return
    }
    clearTimeout(searchTimeout)
    searchTimeout = setTimeout(() => {         
      getSuggest()
    }, 300)
  }

  // 获取搜索结果
  const getSuggest = async () => {
    try {
      const { result } = await searchApi.getSuggest({
        term: inputKeyword.value
      })
      let suggests = []
      if (Object.prototype.toString.call(result) === '[object Object]') {
        const time = new Date().getTime()
        suggests = result.tag.map((item, index) => {
          item.key = time + index
          return item
        })
      } 
      clearSuggests()
      state.suggests.push(...suggests)        
    } catch (error) {
      clearSuggests()
    }
  }

  const triggerSearch = value => {
    clearSuggests()
    value && setHistory(value)
    setStorekeyword(value)      
    router.push({
      name: 'search',
      query: {
        keyword: value
      }
    })
  }

  const clearSuggests = () => {
    state.suggests.splice(0, state.suggests.length)
  }

  const handleCancel = () => {      
    setStorekeyword('')
    router.push({ path: '/' })
  }

  const handleSearch = value => {
    if (value.trim() !== '') {
      triggerSearch(value)
    } else if (state.defaultKey) {
      const { goto_type, url } = state.defaultKey
      if (goto_type === 1) {
          // 直接跳转视频详情页
          const bvid = url.replace(/.*(BV.+)/g, '$1')
          router.push({
            name: 'video',
            params: {
              bvid
            }
          })        
      }
    }
  }

  const setStorekeyword = value => {
    store.commit(`search/${types.SET_SEARCH_KEYWORD}`, value)
    if (value) {
      setStatus('result')
    } else {
      setStatus('init')
    }
  }

  const setHistory = (value) => {
    const vals = getStorage('search_history')
    const matchIndex = vals.findIndex(val => val.value === value)
    if (matchIndex === -1) {
      state.historys.unshift({
        value,
        isHistory: 1,
        timestamp: new Date().getTime()
      })        
      setStorage('search_history', state.historys)
    }
  }

  const setStatus = value => {
    const status = ['init', 'input', 'result']
    const matchStatus = status.includes(value) ? value : 'init'
    state.currentStatus = matchStatus
  }

  // 获取默认的搜索关键字
  const getDefaultKey = async () => {
    try {
      if (state.defaultKey) {
        return
      }
      const { data } = await searchApi.getDefault()
      state.defaultKey = data
    } catch (error) {
      console.log(error)
    }
  }

  // 设置头部显示状态
  store.commit(types.SET_HEADER, false)
    
  onBeforeUnmount(() => {
    store.commit(types.SET_HEADER, true)
  })

  watch(() => route.query, (newVal) => {
    if (route.name === 'search') {
      const { keyword } = newVal
      if (!keyword) {
        setStatus('init')
        getDefaultKey()
      } else {
        inputKeyword.value = keyword
        setStorekeyword(keyword)        
      }        
    }
  }, {
    immediate: true
  })

  return {
    ...toRefs(state),
    inputKeyword,
    handleInput,
    handleCancel,
    handleSearch,
    triggerSearch
  }
}